<?php

class CategoryService extends Service {
	private $model;
	private $tableName;
	private $gid;
	public function __construct(){
		$this->model=M();
	}
	public function setParam($tableName,$gid){
		$this->tableName=$tableName;
		$this->gid=$gid;
	}
	/**
	 * getCategoryList 
	 * 获取所有分类
	 * @Access Public
	 * @Return Void
	 */
	function getCategoryList(){
		$list = F($this->tableName."&gid:".$this->gid);
		if(empty($list)){
			$list=$this->model->query("select a.id , a.name ,a.left_value,a.right_value
							from $this->tableName a
							where gid=$this->gid
							order by left_value
							");
			$list=$this->treeFormat($list);
			F($this->tableName."&gid:".$this->gid,$list);
		}
//		dump($this->model->getLastSql());
		return $list;
	}
		
	
	/**
	 * isLeafCategory 
	 * 检查指定分类是否为叶子节点，是则返回true,否则返回false
	 * @Access Public         
	 * @param mixed $id    
	 * @Return Void
	 */

	public function isLeafCategory($id){
		$list=$this->getOneCategoryInfo($id);
		if($list[0][right_value]-$list[0][left_value]>1){
			return false;
		}else{
			return true;
		}
	}
	/**
	 * getSubCategoryList 
	 * 获取指定分类的子集
	 * @Access Public
	 * @param mixed $id    
	 * @Return Void
	 */

	private function getSubCategoryList($id){
		if( $this->isLeafCategory($id) ){
			return false;
		}
		$list=F($id.$this->tableName);
		if(empty($list)){
			$list=$this->getOneCategoryInfo($id);
			$lft=$list[0]["left_value"];
			$rgt=$list[0]["right_value"];
			
			$list=$this->model->query("select a.id,a.name,a.left_value,a.right_value
							from $this->tableName a
							where a.id=$id
							and a.left_value > $lft
							and a.right_value < $rgt
							and a.gid=$this->gid
							order by left_value");
			$list= $this->treeFormat($list);
			F($id.$this->tableName,$list);
		}
			return $list;
	}
	/**
	 * getCategoryPath 
	 * 获取指定分类的Path
	 * @Access Public
	 * @param mixed $id    
	 * @Return Void
	 */

	function getCategoryPath($id){
		$list=$this->getOneCategoryInfo($id);
		
		$lft=$list[0]["left_value"];
		$rgt=$list[0]["right_value"];
		$list=$this->model->query("select a.id,a.name,a.left_value,a.right_value
						from $this->tableName a
						where a.id=$id
						and a.left_value < $lft
						and a.right_value > $rgt
						and a.gid=$this->gid
						order by left_value");
		$result = array();
		foreach($list as $key=>$val){
			$result[$key]["id"]=$val["id"];
			$result[$key]["name"]=$val["name"];
		}
		return $result;
		
	}
	/**
	 * getBrotherCategoryList 
	 * 获取指定分类的兄弟分类
	 * @Access Public
	 * @param mixed $id    
	 * @Return Void
	 */

	function getBrotherCategoryList($id){
		$pid=$this->getParentCategoryId($id);
		if($pid){
			$list=$this->getSubCategoryList($pid);
		}else{
			$list=$this->getCategoryList();
		}
		$result=array();
		foreach($list as $key=>$val){
			$result[$key]["id"]=$val["id"];
			$result[$key]["name"]=$val["name"];
		}
		return $result;
	}

	/**
	 * moveCategory 
	 * 移动指定分类到$pid下，包括其子级
	 * @Access Public
	 * @param mixed $pid
	 * @param mixed $id    
	 * @Return Void
	 */
	function moveCategory($id, $pid){
		$info=$this->getOneCategoryInfo($id);
		$pinfo=$this->getOneCategoryInfo($pid);
		$lft=$info[0]["left_value"];
		$rgt=$info[0]["right_value"];
		$plft=$pinfo[0]["left_value"];
		$prgt=$pinfo[0]["right_value"];
		$subList=$this->model->query("select a.id,a.name,a.left_value,a.right_value
							from $this->tableName a
							where a.id=$id
							and a.left_value >= $lft
							and a.right_value <= $rgt
							order by left_value");
		if($prgt>$lft){
			//右移
			$step = $rgt-$lft + 1;
			$tmpValue=$prgt-$rgt-1; 
			//处理中间部分
			$this->model->execute("update $this->tableName 
						set left_value=left_value-$step
						where left_value>$rgt
						and left_value<=$plft");
			$this->model->execute("update $this->tableName 
						set right_value=right_value-$step
						where right_value>$rgt
						and right_value<$plft");
			$this->model->execute("update $this->tableName
						set left_value=left_value+$tmpValue,right_value=right_value+$tmpValue
						where left_value >= $lft
						and right_value <= $rgt ");
		}else{
			//左移
			$step = $rgt-$lft + 1;
			$tmpValue=$prgt-$rgt;
			//处理中间部分
			$this->model->execute("update $this->tableName 
						set left_value=left_value+($rgt-$lft)+1 
						where left_value>$prgt
						and left_value<$lft ");
			$this->model->execute("update $this->tableName 
						set right_value=right_value+($rgt-$lft)+1 
						where right_value>=$prgt
						and right_value<$lft ");
			//处理移动部分
			$this->model->execute("update $this->tableName 
						set left_value=left_value-($lft-$plft+1), right_value=right_value-($lft-$plft+1)
						where left_value >= $lft
						and right_value <= $rgt");
		}
		$this->freeCategoryCach();
	}
	
	/**
	 * deleteCategory 
	 * 删除指定分类
	 * @Access Public
	 * @param mixed $id    
	 * @Return Void
	 */
	function deleteCategory($id){
		$list=$this->getOneCategoryInfo($id);
		$lft=$list[0]["left_value"];
		$rgt=$list[0]["right_value"];
		$name=$list[0]["name"];
		$this->model->execute("delete from $this->tableName where left_value>=$lft and right_value <=$rgt and gid=$this->gid");
		$this->model->execute("update $this->tableName 
					set left_value=left_value-($rgt-$lft+1)
					where left_value>$lft
					and gid=$this->gid");
		$this->model->execute("update $this->tableName 
					set right_value=right_value-($rgt-$lft+1) 
					where right_value>$rgt
					and gid=$this->gid");
		$this->freeCategoryCach();
		return true;
	}

	/**
	 * addCategory 
	 * 添加分类,每次添加都是在第一个位置
	 * @Access Public
	 * @param mixed $pid    
	 * @param mixed $id    
	 * @Return Void
	 */
	function addCategory($pid, $name){
		//todo:考虑同名分类拉通
		if($pid!=0){
			$list=$this->getOneCategoryInfo($pid);
			$lft=$list[0]["left_value"];
			$rgt=$list[0]["right_value"];
			$list=$this->model->query("select id from $this->tableName a where name='$name'.asdf and gid=$this->gid");
			if(empty($list)){
				$this->model->execute("update $this->tableName a set left_value=left_value+2 where left_value>$lft and a.gid=$this->gid");
				$this->model->execute("update $this->tableName a set right_value=right_value+2 where right_value>=$lft and a.gid=$this->gid");
				$this->model->execute("insert into $this->tableName 
							(name,gid,left_value,right_value) values
							('$name','$this->gid',$lft+1,$lft+2)");
			}else{
				return 0;
			}
			
		}else{
			//添加一级分类
			$list=$this->model->query("select id from $this->tableName a  where a.name='$name' and a.gid=$this->gid");
			if(!empty($list)){
				return 0;
			}
			$max=$this->model->query("select max(right_value)  from $this->tableName a where a.gid=$this->gid");
			$lft=$max[0]['max(right_value)']+1;
			$this->model->execute("insert into $this->tableName 
						(name,gid,left_value,right_value) values
						('$name','$this->gid',$lft,$lft+1)");
			
		}
		$this->freeCategoryCach();
		return $this->model->getLastInsID ();
	}
	/**
	 * editCategory 
	 * 编辑分类
	 * @Access Public
	 * @param mixed $id    
	 * @Return Void
	 */	
	function editCategory($id,$name){
		$list=$this->getOneCategoryInfo($id);
		if($list){
			$this->model->execute("update $this->tableName 
									set name='$name'
									where id=$id");
			$err=$this->model->getDbError();
			if(empty($err)){
				$this->freeCategoryCach();
				return true;
			}else{
				return false;
			}
		}else{
			return false;
		}
	}
	/**
	 * getParentCategoryId 
	 * 取得父类的ID
	 * @Access Public
	 * @param mixed $id    
	 * @Return Void
	 */	
	private function getParentCategoryId($id){		
		$list=$this->getOneCategoryInfo($id);
		$lft=$list[0]["left_value"];
		$rgt=$list[0]["right_value"];
		$list=$this->model->query("select a.id,a.name,a.left_value,a.right_value
						from $this->tableName a
						where a.tag_id=b.tag_id
						and a.left_value < $lft
						and a.right_value > $rgt
						and a.gid=$this->gid
						order by left_value desc");
		if(isset($list)){
			return $list[0]['id'] ;
		}else{
			return false; 
		}
	}
	/**
	 * getOneCategoryInfo 
	 * 读取 个分类的信息
	 * @Access Public
	 * @param mixed $id    
	 * @Return Void
	 */	
	function getOneCategoryInfo($id){
		$this->checkParmIsId($id);
		$list=$this->model->query("select a.id,a.name,a.left_value,a.right_value
						from $this->tableName a
						where a.id=$id
						and a.gid=$this->gid");
		//echo $this->model->getLastSql();
		if(empty($list)){
			throw new ThinkException('不存在分类ID为'.$id."的分类");
		}
		return $list;
	}
	private function checkParmIsId($id){
		if(!is_numeric($id)){
			throw new ThinkException('参数必须为数字');
		}else if($id==0){
			throw new ThinkException('参数不能为0');
		}else{
			return true;
		}
	}
	/**
	 * treeFormat 
	 * 转换为树形结构
	 * @Access Public
	 * @param mixed $data    
	 * @Return Void
	 */
	private function treeFormat($data) {
		foreach ( $data as $key1 => $value ) {
			$list [] = $value;
			foreach ( $list as $key2 => $v ) {
				if ($value ['left_value'] > $v ['left_value'] && $value ['right_value'] < $v ['right_value']) {
					$list [$key2] ['children'] [] = $value;
					array_pop ( $list );
				}
			}
		}
		foreach ( $list as &$value ) {
			if (isset ( $value ['children'] )) {
				$value ['children'] = $this->treeFormat ( $value ['children'] );
			}
		}
		return $list;
	}
	/**
	 * freeCategoryCach 
	 * 清除分类的缓存
	 * @Access Public
	 * @Return Void
	 */
	private function freeCategoryCach(){
		F($this->tableName."&gid:".$this->gid,NULL);
		$list=$this->model->query("select id from $this->tableName");
		foreach ($list as $key=>$val){
			F($val['id'].$this->tableName,NULL);
		}
	}
	/**
	 * savetree 
	 * 存储树形为左右值记录
	 * @Access Public
	 * @param mixed $data,分类ID的树形数据    
	 * @param mixed $i     
	 * @Return Void
	 */
	function saveTree($data,&$i=1) {
		foreach($data as $key=>$val){
			$id=$val['id'];
			$this->model->execute("update $this->tableName  set left_value=$i where id=$id and gid=$this->gid");
			$i++;
			if( isset($val['children'])){
				$this->savetree($val['children'],$i);
			}
			$this->model->execute("update $this->tableName  set right_value=$i where id=$id and gid=$this->gid");
			$i++;
		}
		
		$this->freeCategoryCach();
		$err=$this->model->getDbError();
		if(empty($err)){
			return true;
		}else{
			return false;
		}
	}
	
	function makeTreeHtml($list){
		$str='<span id="spans-divs" class="page-list">';
		foreach($list as $key=>$val){
			$str=$str.'<div id='.$val["id"].' class="clear-element page-item3 sort-handle left_al"><div><span id="title_'.$val["id"].'">'.$val["name"].'</span>';
			$str=$str.'	<a href="javascript:void(0)" onclick="del('.$this->gid.','.$val["id"].');">删除</a>
			<a href="javascript:void(0)" onclick="edit('.$this->gid.','.$val["id"].');">编辑</a> 
			<a href="javascript:void(0)" onclick="add('.$this->gid.','.$val["id"].');">添加</a>';
			$str=$str.'</div>';
			if(isset($val["children"])){
				$temp=$this->makeTreeHtml($val["children"]);
				$str=$str.$temp;
			}
			$str=$str.'</div>';
		}
		$str=$str.'</span>';
		return $str;
	}
	
	function makeTreeHtmlForUser($list,$i=false){
		$html = $i?"<ul class='treemenu'>":"<ul >";
		foreach($list as $key=>$val){
			$html .= "<li class='btm' id='li_".$val["id"]."'>";
			$html .= "<a id='drop_".$val["id"]."' class='drop' href='javascript:void(0)' onclick='getFileHtml(".$val["id"].")'>";//<img src='/kmp/apps/group/Tpl/default/Public/images/treeimg/folder.gif'/>";
			$html .= $val['name']."</a>";
			
			if(isset($val["children"])){			
				$html .= $this->makeTreeHtmlForUser($val['children'],false)."</li>";
			}
		}
		return $html."</ul>";
	}
	function  _format($list){
		foreach ($list as $key=>$val){
			$res[$key]['a']=$val['id'];
			$res[$key]['t']=$val['name'];
			if( isset($val['children']) ){
				$res[$key]['d']=$this->_format($val['children']);
			}
		}
		return $res;
	}
	public function _start(){
		return true;
	}
	public function run(){
		return true;
	}
	
	public function _stop(){
		return true;
	}

	public function _install(){
		return true;
	}

	public function _uninstall(){
		return true;
	}
	
	
}
?>